new.ios.pkg.sh() {
    cat <<EOF >>pkg.sh
#!/bin/sh

build_configuration="Release"
# 在用户和访问->密钥 里生成：https://appstoreconnect.apple.com/access/api
appstore_apiKey="8K7SCLZ7X7"
appstore_apiIssuer="69a6de91-cea3-47e3-e053-5b8c7c11a4d1"

function change_build_version() {
    cd \$(dirname \$(get_xcworkspace_path))
    # 1: 使用数字作为build版本号:
    agvtool next-version -all # build号自增1
    # 2: 使用时间作为build版本号:
    # new_build_version=\$(date '+%Y%m%d_%H%M%S')
    # agvtool new-version -all $new_build_version
}

function change_version() {
    cd \$(dirname \$(get_xcworkspace_path))
    new_version=\$(date '+%Y%m%d_%H%M%S')
    agvtool new-marketing-version $new_version
}

function get_scheme_name() {
    xcworkspace_path=\$(get_xcworkspace_path)
    file_name=\$(basename $xcworkspace_path)
    scheme_name="${file_name%%.*}"
    echo $scheme_name
}

function get_xcworkspace_path() {
    work_dir=\$(dirname $0)
    xcworkspace_path=''
    for file in \$(find $work_dir -maxdepth 1 -name *.xcworkspace); do
        xcworkspace_path=$file
    done

    if [ -n "$xcworkspace_path" ]; then
        echo $xcworkspace_path
    else
        for file in \$(find $work_dir -maxdepth 1 -name *.xcodeproj); do
            xcworkspace_path=$file
        done

        if [ -n "$xcworkspace_path" ]; then
            echo $xcworkspace_path
        else
            echo "No xcode files to open."
        fi
    fi
}

function clean() {
    error_log=\$(dirname $0)/build/error.log
    rm -rf $error_log
    mkdir -p \$(dirname $0)/build/ 1>/dev/null 2>&1
    rm -rf $export_options_plist_path # 每次都重新生成
    xcodebuild clean -workspace \$(get_xcworkspace_path) \
        -scheme \$(get_scheme_name) \
        -configuration ${build_configuration} 2>$error_log
}

function archive() {
    archive_path=\$(dirname $0)/build/\$(get_scheme_name).xcarchive
    xcodebuild archive -workspace \$(get_xcworkspace_path) \
        -scheme \$(get_scheme_name) \
        -configuration ${build_configuration} \
        -archivePath ${archive_path} 2>$error_log

    if [ -d "$archive_path" ]; then
        echo "\033[32;1marchive成功 🚀 🚀 🚀  \033[0m"
    else
        echo "\033[31;1marchive失败 😢 😢 😢  \033[0m"
        exit 1
    fi
}

function create_export_plist() {
    export_options_plist_path=\$(dirname $0)/exportOptions.plist
    method="app-store" # ad-hoc, app-store, enterprise, development
    # 根据参数生成export_options_plist文件
    /usr/libexec/PlistBuddy -c "Add :method String ${method}" $export_options_plist_path
    #/usr/libexec/PlistBuddy -c  "Add :provisioningProfiles:"  $export_options_plist_path
    #/usr/libexec/PlistBuddy -c  "Add :provisioningProfiles:${bundle_identifier} String ${mobileprovision_name}"  $export_options_plist_path
    /usr/libexec/PlistBuddy -c "Add :signingStyle String automatic" $export_options_plist_path
    /usr/libexec/PlistBuddy -c "Add :destination String export" $export_options_plist_path
    /usr/libexec/PlistBuddy -c "Add :compileBitcode bool false" $export_options_plist_path #如果您的工程是开启Bitcode的话，请把false改为true
}

function archive_to_ipa() {
    output_ipa_dir=\$(dirname $0)/build/ipa
    create_export_plist
    xcodebuild -exportArchive \
        -archivePath ${archive_path} \
        -exportPath ${output_ipa_dir} \
        -exportOptionsPlist ${export_options_plist_path} \
        -allowProvisioningUpdates 2>$error_log

    ipa_path=""
    for file in \$(find $output_ipa_dir -maxdepth 1 -name *.ipa); do
        ipa_path=$file
    done

    if [ -f $ipa_path ]; then
        echo "\033[32;1m导出ipa成功 🚀 🚀 🚀  \033[0m"
    else
        echo "\033[31;1m导出ipa失败 😢 😢 😢  \033[0m"
        exit 1
    fi
    echo $ipa_path
}

function upload_to_appletore() {
    $ipa_path=""
    ipa_path=""
    for file in \$(find $output_ipa_dir -maxdepth 1 -name *.ipa); do
        ipa_path=$file
    done
    xcrun altool --validate-app -f $ipa_path -t ios --apiKey $appstore_apiKey --apiIssuer $appstore_apiIssuer --verbose
    xcrun altool --upload-app -f $ipa_path -t ios --apiKey $appstore_apiKey --apiIssuer $appstore_apiIssuer --verbose
}

function main() {
    clean
    change_build_version
    archive
    archive_to_ipa
    upload_to_appletore
}

main

EOF
}

new.eslintrc.js() {
    cat <<EOF >>.eslintrc.js
module.exports = {
  parser: "vue-eslint-parser", // 指定ESLint解析器
  parserOptions: {
    sourceType: "module", // 允许使用导入
    parser: "@typescript-eslint/parser",
  },
  extends: [
    "plugin:@typescript-eslint/recommended", // 使用@ typescript-eslint / eslint-plugin中的推荐规则
    // "prettier/@typescript-eslint", // 使用eslint-config-prettier禁用一些与Prettier冲突的ESLint规则
    "prettier", // 使用eslint-config-prettier禁用一些与Prettier冲突的ESLint规则
    "plugin:prettier/recommended", // 启用eslint-plugin-prettier和eslint-config-prettier，使编辑器显示错误提示，确保这项是扩展数组中的最后一个配置
  ],
  rules: {
    // 放置ESLint规则的位置。可用于覆盖从扩展配置中指定的规则
    // 例如 "@typescript-eslint/explicit-function-return-type": "off",
  },
};
EOF
}

new.vue.config.js() {
    cat <<EOF >>vue.config.js

EOF
}

new.Dockerfile() {
    cat <<EOF >>Dockerfile
FROM alpine

RUN apt update && apt install -y \
    xxx \
    yyy \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY ./xxx /app/xxx
EXPOSE 443

ENTRYPOINT [ "/app/xxx"]
EOF
}

new.docker-compose.yml() {
    cat <<EOF >>docker-compose.yml
version: "3"
services:
  goapp_xxx:
    container_name: goapp_xxx
    image: alpine
    restart: always
    env_file: ./.env
    volumes:
      - ./xxx:/app/xxx
    ports:
      - 80:80
    depends_on:
      - mongo
    entrypoint: ["/app/xxx"]

networks:
  default:
    external:
      name: xxx
  frontend:
    driver: custom-driver-1
  backend:
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

EOF
}

new.gitignore.vue() {
    cat <<EOF >>.gitignore
**/node_modules
EOF
}

new.gitignore.xcode() {
    cat <<EOF >>.gitignore
# Xcode

#

# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore

## User settings

xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)

*.xcscmblueprint

*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)

build/

DerivedData/

*.moved-aside

*.pbxuser

!default.pbxuser

*.mode1v3

!default.mode1v3

*.mode2v3

!default.mode2v3

*.perspectivev3

!default.perspectivev3

## Obj-C/Swift specific

*.hmap

## Xcode Patch

*.xcodeproj/*

!*.xcodeproj/project.pbxproj

!*.xcodeproj/xcshareddat

!*/xcuserdata/admin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlista/

!*.xcworkspace/contents.xcworkspacedata

/*.gcno

## App packaging

*.ipa

*.dSYM.zip

*.dSYM

# CocoaPods

#

# We recommend against adding the Pods directory to your .gitignore. However

# you should judge for yourself, the pros and cons are mentioned at:

# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control

#

Pods/

Podfile.lock

#

# Add this line if you want to avoid checking in source code from the Xcode workspace

*.xcworkspace

# Carthage

#

# Add this line if you want to avoid checking in source code from Carthage dependencies.

# Carthage/Checkouts

Carthage/Build/

# fastlane

#

# It is recommended to not store the screenshots in the git repo.

# Instead, use fastlane to re-generate the screenshots whenever they are needed.

# For more information about the recommended setup visit:

# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml

fastlane/Preview.html

fastlane/screenshots/**/*.png

fastlane/test_output

# Mac OS X Finder and whatnot

.DS_Store

EOF
}

new.gitignore.go() {
    cat <<EOF >>.gitignore

EOF
}

new.nginx.server.conf() {
    cat <<EOF >>nginx.server.conf
server {
    listen 80;
    server_name "localhost";

    rewrite ^(.*)$ https://$host$1 permanent;
}

server {
    listen 443 ssl;
    server_name discovery.u-nas.cn;

    ssl_certificate /root/4766641_discovery.u-nas.cn.pem;
    ssl_certificate_key /root/4766641_discovery.u-nas.cn.key;

    location / {
        proxy_set_header Host host;
        proxy_set_header X-real-ip remote_addr;
        proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for;

        proxy_pass http://127.0.0.1:8888;
    }

    location /static {
        root /path/to/static_dir/;
        autoindex on; # 开启文件目录服务
    }

}
EOF
}

new.nginx.server.php.conf() {
    cat <<EOF >>nginx.conf
server {
    listen 80;
    index index.php index.html;
    server_name _;
    root /var/www/html; #php代码路径

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
EOF
}

new.nginx.conf() {
    cat <<EOF >>nginx.conf
user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;


events {
    worker_connections 1024;
}


http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main
        '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    #tcp_nopush     on;

    keepalive_timeout 65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
EOF
}

new.index.html() {
    cat <<EOF >>index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>hello</h1>
</body>

</html>
EOF
}

new.init-mongo.js() {
    cat <<EOF >>init-mongo.js
print('Start #################################################################');
db = db.getSiblingDB('admin'); // 把数据库 admin设置为授权数据库, 相当于 use test_db
db.createUser(
    {
        user: "test",
        pwd: "test",
        roles: [
            {
                role: "readWrite",
                db: "test_db" // 设置对数据库 test_db的操作权限，test_db为业务数据库
            }
        ]
    }
);
db = db.getSiblingDB('test_db'); // 相当于 use test_db
db.createCollection('test'); // 创建测试集合，验证 mongo初始化成功,登录navi可以立马看到
print('END #################################################################');

db.createCollection('user');
// 创建普通索引:
db.user.createIndex({ name: 1 }); // 1代表升序， -1代表降序
// 创建组合索引:
db.user.createIndex({ name: -1, age: 1 });
// 设置TTL索引:
db.user.createIndex({ name: 1 }, { expireAfterSeconds: 60, background: true }) //expireAfterSeconds为过期时间（单位秒)
// 创建unique索引:
db.user.createIndex({ name: -1 }, { unique: false });

EOF
}

new.npmrc() {
    cat <<EOF >>.npmrc
registry = https://registry.npm.taobao.org
strict-ssl = false
phantomjs_cdnurl = https://npm.taobao.org/mirrors/phantomjs/
electron_mirror = https://npm.taobao.org/mirrors/electron/
EOF
}

new.yarnrc() {
    cat <<EOF >>.yarnrc
registry "http://registry.npm.taobao.org"
sass_binary_site "https://npm.taobao.org/mirrors/node-sass/"

phantomjs_cdnurl "http://cnpmjs.org/downloads"
electron_mirror "https://npm.taobao.org/mirrors/electron/"
sqlite3_binary_host_mirror "https://foxgis.oss-cn-shanghai.aliyuncs.com/"
profiler_binary_host_mirror "https://npm.taobao.org/mirrors/node-inspector/"
chromedriver_cdnurl "https://cdn.npm.taobao.org/dist/chromedriver"
puppeteer_download_host https://npm.taobao.org/mirrors
EOF
}

new.requirements.txt() {
    cat <<EOF >>requirements.txt
fastapi>=0.68.0,<0.69.0
pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0
debugpy
EOF
}

new.webpack.config.js() {
    cat <<EOF >>webpack.config.js
const path = require('path');

const config = {
    entry: './path/to/entry_file.js',
    mode: 'production', // development | production
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'my-first-webpack.bundle.js'
    },
    module: {
        rules: [
            { test: /\.txt$/, use: 'raw-loader' }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({ template: './src/index.html' })
    ]
};

module.exports = config;

EOF
}

new.vite.config.js() {
    cat <<EOF >>vite.config.js
import { defineConfig } from "vite";
import { resolve } from "path";
import vue from '@vitejs/plugin-vue';

function pathResolve(dir) {
    return resolve(__dirname, ".", dir);
}

export default defineConfig({
    base: "",
    plugins: [vue()],
    resolve: {
        alias: {
            "/@": pathResolve("src"),
        }
    },
    optimizeDeps: {
        include: ['axios'],
    },
    build: {
        target: 'modules',
        outDir: 'dist',
        assetsDir: 'assets',
        minify: 'terser' // 混淆器
    },
    server: {
        cors: true,
        open: true,
        proxy: {
            '/api': {
                target: 'http://192.168.99.223:3000',   //代理接口
                changeOrigin: true,
                rewrite: (path) => path.replace(/^\/api/, '')
            }
        }
    }
});

EOF
}

new.vite.config.ts() {
    cat <<EOF >>vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    open: true,
  },
  resolve: {
    alias: {
      // 如果报错__dirname找不到，需要安装node,执行yarn add @types/node --save-dev
      "@": path.resolve(__dirname, "src"),
      comps: path.resolve(__dirname, "src/components"),
    },
  },
});
EOF
}

new.deploy.sh() {
    cat <<REALEND >>deploy.sh
deploy_docker_compose() {
    remote=\$1
    proj_name=\$2
    local_dir=\$(dirname \$0)
    remote_dir=/opt/\$proj_name

    ssh \$remote <<EOF
        docker-compose -f \$remote_dir/docker-compose.yml down
        rm -rf \$remote_dir
EOF
    scp -r \$local_dir \$remote:\$remote_dir
    ssh \$remote <<EOF
    rm -rf \$remote_dir/deploy.sh
    docker network create nginx
    docker-compose -f \$remote_dir/docker-compose.yml up -d --build
EOF
}

deploy_docker_compose root@banli.site nginx
REALEND

}

new.httpd.conf() {

}

# npm install:

new.go.mod() {
    if [ $# != 1 ]; then
        echo "#### 使用方法: new.go.mod demo_xxx"
        return
    fi
    go mod init $1
}

new.package.json() {
    if [ -x "$(command -v yarn)" ]; then
        yarn init -yp
        return
    fi
    npm init -yp
}

# prettier格式化配置文件:
new.prettierrc.js() {
    cat <<EOF >>.prettierrc.js
module.exports = {
    singleQuote: true,
    trailingComma: 'es5',
    printWidth: 120,
    tabWidth: 4,
    useTabs: false,
    semi: false,
    bracketSpacing: true
};
EOF
}

new.jsconfig.json() {
    cat <<EOF >>jsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6"
  },
  "exclude": ["node_modules"]
}
EOF
}

# typescript编译配置文件:
new.tsconfig.json() {
    cat <<EOF >>tsconfig.json
{
    "compilerOptions": {
        "strict": true,
        "target": "esnext",
        "module": "commonjs",
        "noImplicitAny": true,
        "moduleResolution": "node",
        "sourceMap": true,
        "outDir": "dist",
        "baseUrl": ".",
        "paths": {
            "*": [
                "node_modules/*",
                "src/types/*"
            ]
        },
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules"
    ]
}
EOF
}

# 新建xxx.service文件:
new.systemd.service() {
    if [ $# != 1 ]; then
        echo "#### 使用方法: new.systemd.service service_name"
    fi
    name=$1
    cat >$name.service <<EOF
[Unit]
Description=$name service
After=network.target

[Service]
Type=simple
User=root
RuntimeMaxSec=604800
Restart=on-failure
RestartSec=1s
WorkingDirectory=/opt/$name
ExecStart=/opt/$name/$name
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

EOF
}

new.systemd.service.timer() {
    if [ $# != 1 ]; then
        echo "#### 使用方法: new.systemd.service.timer service_name"
    fi
    name=$1
    cat >$name.service <<EOF
[Unit]
Description=$name service

[Timer]
OnUnitActiveSec=1h  # 1小时执行一次
Unit=xxx.service

[Install]
WantedBy=multi-user.target
EOF
}

new.plist.file.timer() {
    name=$1
    cat >$name.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>$name</string>
    <key>RunAtLoad</key>
    <true/>
    <key>ProgramArguments</key>
    <array> <string>/Users/denglibing/Desktop/denglibing_checkin/denglibing_checkin_request.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Weekday</key>
            <integer>1</integer>
            <key>Hour</key>
            <integer>8</integer>
            <key>Minute</key>
            <string>58</string>
        </dict>
        <dict>
            <key>Weekday</key>
            <integer>2</integer>
            <key>Hour</key>
            <integer>8</integer>
            <key>Minute</key>
            <string>52</string>
        </dict>
    </array>
    <key>StandardOutPath</key>
    <string>/Users/denglibing/Desktop/denglibing_checkin/outlog</string>
    <key>StandardErrorPath</key>
    <string>/Users/denglibing/Desktop/denglibing_checkin/errorlog</string>
</dict>
</plist>
EOF
}

new.httpie() {
    if [ $# != 1 ]; then
        echo "#### 使用方法: new.httpie name"
    fi
    name=$1
    cat >$name.httpie <<EOF

// get
http GET localhost:80/xxx
xxx==111
yyy==222


// post-json
http -j POST localhost:80/path_xxx
xxx:=111
yyy=222


// post-form：
http -f POST localhost:80/path_xxx
xxx=111
yyy=222


// 自定义header
http GET localhost:80/path_xxx
xxx==111
yyy==222
"User-Agent:Bacon/1.0"
"Cookie:valued-visitor=yes;foo=bar"
"name:0000"
-v

// 上传文件
http -f POST localhost:80/upload
xxx='xxx'
file_xxx@~/xxx/xxx.pdf
EOF
}
